/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sgsmcan.Controlador;

import com.sgsmcan.Dao.AmoDao;
import com.sgsmcan.Dao.AmoDaoImpl;
import com.sgsmcan.Dao.UbigeoDao;
import com.sgsmcan.Dao.UbigeoDaoImpl;
import com.sgsmcan.Entidad.Amo;
import com.sgsmcan.Entidad.Perro;
import com.sgsmcan.Entidad.Ubigeo;
import com.sgsmcan.EntidadFiltro.AmoFiltro;
import com.sgsmcan.Exporter.Exporter;
import com.sgsmcan.Utils.DataExporter;
import com.sgsmcan.Utils.FiltroHibernate;
import com.sgsmcan.Utils.Paginacion;
import com.sgsmcan.Utils.SetUbigeo;
import com.sgsmcan.Utils.Utilitario;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.NavigationHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.hibernate.criterion.DetachedCriteria;
import org.primefaces.model.LazyDataModel;

/**
 *
 * @author user
 */
@ManagedBean(name = "donanteBean")
@ViewScoped
public class DonanteControlador implements Serializable {

    private AmoDao daoAmo;
    private UbigeoDao daoUbigeo;
    private Amo amo;
    private AmoFiltro amoFiltro;
    private Ubigeo ubi;
    private LazyDataModel<Amo> amos;
    private String auxiliarDni = null;/*para el caso de la actualizacion*/
    
    /*id para eliminar donante*/
    public int idDonante;
    
    /*Variables para controlar el flujo de Ubigeo*/
    SetUbigeo mapaUbigeo ;
    List<SelectItem> departamentos;
    List<SelectItem> provincias; 
    List<SelectItem> distritos; 
    
    String idDepartamento;
    String idProvincia;
    String idDistrito;
    @ManagedProperty("#{usuarioBean}")
    private UsuarioControlador usuarioSesion;

    public DonanteControlador() {
        daoAmo = new AmoDaoImpl();
        daoUbigeo = new UbigeoDaoImpl();
        amo = new Amo();
        amoFiltro = new AmoFiltro();
    }

    public void initLista() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            usuarioSesion.generarModulo(5);
            amos = new Paginacion<Amo>(daoAmo.getAmos());
        }
    }
    
    public void initInsertar(){
        if (!FacesContext.getCurrentInstance().isPostback()) {
            mapaUbigeo = new SetUbigeo();
            ensamblarUbigeo();
        }
    }
    
    private void ensamblarUbigeo(){
        departamentos = new ArrayList<SelectItem>();
        provincias = new ArrayList<SelectItem>();
        distritos = new ArrayList<SelectItem>();
        List<Ubigeo> ubigeos = daoUbigeo.getUbigeos();
        for(Ubigeo ubige : ubigeos){
            mapaUbigeo.addUbigeo(ubige);
        }
        departamentos = mapaUbigeo.getDepartamentos();
        provincias = mapaUbigeo.getProvincia("0");
        distritos = mapaUbigeo.getDistrito("0","0");

    }
    
    public void cambiarDepartamentos(){ 
        provincias = mapaUbigeo.getProvincia(idDepartamento);
        distritos = mapaUbigeo.getDistrito("0","0");
    }
    
    public void cambiarProvincias(){
        distritos = mapaUbigeo.getDistrito(idDepartamento,idProvincia);
    }

    public void initUpdate() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            Object parametro = FacesContext.getCurrentInstance().getExternalContext().getFlash().get("idDonante");
            if (parametro == null) {
                FacesContext fc = FacesContext.getCurrentInstance();
                NavigationHandler nh = fc.getApplication().getNavigationHandler();
                nh.handleNavigation(fc, null, "/views/donante/list.xhtml?faces-redirect=true");
                return;
            }
            Integer id = (Integer) parametro;
            amo = (Amo) daoAmo.getAmo(id);
            auxiliarDni = amo.getDni();
            mapaUbigeo = new SetUbigeo();
            ensamblarUbigeo();
            ubi = (Ubigeo) daoUbigeo.getUbigeo(amo.getCodigoUbigeo());
            idDepartamento = ubi.getCodigoDepartamento();
            cambiarDepartamentos();
            idProvincia = ubi.getCodigoProvincia();
            cambiarProvincias();
            idDistrito = ubi.getCodigoDistrito(); 
        }
    }

    public String irActualizar(Integer id) {
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("idDonante",id);
        return "update.xhtml?faces-redirect=true";
    }

    public void actualizarAmo(ActionEvent evnt) {
        if (!esValido()) {
            return;
        }
        try {
            amo.setCodigoUbigeo(ubi.getId());
            daoAmo.actualizar(amo);
        } catch (Exception e) {
            Utilitario.enviarMensajeGlobalError("Error en el sistema");
            Utilitario.LOG.error("Error en DonanteControlador", e);
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha actualizado correctamente");
    }

    public void insertarAmo(ActionEvent evnt) {
        if (!esValido()) {
            return;
        }
        try {
            amo.setEstado(Boolean.TRUE);
            amo.setCodigoUbigeo(ubi.getId());
            daoAmo.insertar(amo);
        } catch (Exception e) {
            Utilitario.enviarMensajeGlobalError("Error en el sistema");
            Utilitario.LOG.error("Error en DonanteControlador", e);
            return; 
        }
        limpiar();
        Utilitario.enviarMensajeGlobalValido("Se ha guardado correctamente");
    }
    
    public void prepararEliminacion(Integer id){
        idDonante = (int)id;
    }
    
    public void eliminarDonante(ActionEvent event){ 
        amo = (Amo) daoAmo.getAmo(idDonante);
        amo.setEstado(Boolean.FALSE);
        daoAmo.eliminar(amo);
        Utilitario.enviarMensajeGlobalValido("Se ha eliminado correctamente");
    }

    private boolean esValido() {
        if (!esNombreDonanteValido()) {
            return false;
        }
        if (!esApellidoDonanteValido()) {
            return false;
        }
        if (!esDniDonanteValido()) {
            return false;
        }
        if(!esTelefonoValido()){
            return false;
        }
        if(!esCelularValido()){
            return false;
        }
        if(!esDepartamentoValido()){
            return false;
        }
        if(!esProvinciaValida()){
            return false;
        }
        if(!esDistritoValido()){
            return false;
        }
        if(!esDireccionValida()){
            return false;
        }
        if(!esUbigeoValido()){
            return false;
        }
        return true;
    }

    private boolean esNombreDonanteValido() {
        if (Utilitario.esNulo(amo.getNombre())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el nombre del Donante");
            return false;
        } else if (!Utilitario.esSoloLetras(amo.getNombre())) {
            Utilitario.enviarMensajeGlobalError("El nombre del Donante debe ser solo letras");
            return false;
        } else if (!Utilitario.esRangoValido(amo.getNombre(), 100)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del nombre del Donante es 100");
            return false;
        }
        return true;
    }

    private boolean esApellidoDonanteValido() {
        if (Utilitario.esNulo(amo.getApellido())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar los Apellidos del Donante");
            return false;
        } else if (!Utilitario.esSoloLetras(amo.getApellido())) {
            Utilitario.enviarMensajeGlobalError("Los apellidos del Donante deben ser solo letras");
            return false;
        } else if (!Utilitario.esRangoValido(amo.getApellido(), 100)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres de los Apellidos del Donante es 100");
            return false;
        }
        return true;
    }

    private boolean esDniDonanteValido() {
        if (Utilitario.esNulo(amo.getDni())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el DNI del Donante");
            return false;
        } else if (amo.getDni().length() != 8) {
            Utilitario.enviarMensajeGlobalError("La cantidad de digitos del DNI es 8");
            return false;
        }
        if(auxiliarDni == null && daoAmo.existeDni(amo.getDni())){
            Utilitario.enviarMensajeGlobalError("Ya existe el dni en el sistema");
            return false;
        }else if(auxiliarDni != null && !auxiliarDni.equalsIgnoreCase(amo.getDni()) && daoAmo.existeDni(amo.getDni())){
            Utilitario.enviarMensajeGlobalError("Ya existe el dni en el sistema");
            return false;    
        }
        return true;
    }
    
    private boolean esTelefonoValido(){
        if (Utilitario.esNulo(amo.getTelefono())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el Teléfono");
            return false;
        }else if(amo.getTelefono().length() != 7){
            Utilitario.enviarMensajeGlobalError("El Teléfono debe ser 7 digitos");
            return false;
        }
        return true;
    }
    
    private boolean esCelularValido(){
        if (!Utilitario.esNulo(amo.getCelular()) && amo.getCelular().length() != 9) {
            Utilitario.enviarMensajeGlobalError("El celular debe ser 9 digitos");
            return false;
        }
        return true;
    }
    
    private boolean esDireccionValida(){
        if(Utilitario.esNulo(amo.getDireccion())){
            Utilitario.enviarMensajeGlobalError("Debe ingresar la dirección");
            return false;
        }
        return true;
    }
    
    private boolean esDepartamentoValido(){
        if(idDepartamento.equals("0")){
            Utilitario.enviarMensajeGlobalError("Debe seleccionar el departamento");
            return false;
        }
        return true;
    }
    
    private boolean esProvinciaValida(){
        if(idProvincia.equals("0")){
            Utilitario.enviarMensajeGlobalError("Debe seleccionar una provincia");
            return false;
        }
        return true;
    }
    
    private boolean esDistritoValido(){
        if(idDistrito.equals("0")){
            Utilitario.enviarMensajeGlobalError("Debe seleccionar un distrito");
            return false;
        }
        return true;
    }
    
    private boolean esUbigeoValido(){
        ubi = (Ubigeo) daoUbigeo.getUbigeo(idDepartamento,idProvincia, idDistrito);
        if( ubi == null){
            Utilitario.enviarMensajeGlobalError("Los datos del Ubigeo no son correctos");
            return false;
        }
        
        return true;
    }

    private void limpiar() {
        amo = new Amo();
    }
    
    public void exportar(ActionEvent event) {
        Paginacion<Amo> paginacion = (Paginacion<Amo>) amos;
        List<Amo> lista = paginacion.getAllList();
        if (lista.isEmpty()) {
            return;
        }
        Exporter exporter = lista.get(0);
        DataExporter<Amo> dataExporter = new DataExporter<Amo>(exporter);
        dataExporter.crearDocumento(lista);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext = DataExporter.getResponseContent(externalContext,"donantes");
        try {
            OutputStream outputStream = externalContext.getResponseOutputStream();
            dataExporter.exportarDocumento(outputStream);
            externalContext.setResponseStatus(200);
            externalContext.responseFlushBuffer();
            facesContext.responseComplete();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    
    public void buscarFiltro(ActionEvent event){
        FiltroHibernate hibernate = new FiltroHibernate(daoAmo.getAmos());
        hibernate.addLikeNullParametro(amoFiltro.getNombre(),"amo.nombre");
        hibernate.addLikeNullParametro(amoFiltro.getApellidos(),"amo.apellido");
        hibernate.addLikeNullParametro(amoFiltro.getDni(),"amo.dni");
        hibernate.addLikeNullParametro(amoFiltro.getTelefono(),"amo.telefono");
        DetachedCriteria criteria = hibernate.executeFiltro();
        amos = new Paginacion<Amo>(criteria);
    }
    
    public void limipiarFiltro(ActionEvent event){
        amos = new Paginacion<Amo>(daoAmo.getAmos());
        amoFiltro = new AmoFiltro();
    }
    
    /*GETTER AND SETTER*/
    public Amo getAmo() {
        return amo;
    }

    public void setAmo(Amo amo) {
        this.amo = amo;
    }

    public LazyDataModel<Amo> getAmos() {
        return amos;
    }

    public void setAmos(LazyDataModel<Amo> amos) {
        this.amos = amos;
    }

    public int getIdDonante() {
        return idDonante;
    }

    public void setIdDonante(int idDonante) {
        this.idDonante = idDonante;
    }

    public List<SelectItem> getDepartamentos() {
        return departamentos;
    }

    public void setDepartamentos(List<SelectItem> departamentos) {
        this.departamentos = departamentos;
    }
    
    public List<SelectItem> getProvincias() {
        return provincias;
    }

    public void setProvincias(List<SelectItem> provincias) {
        this.provincias = provincias;
    }

    public List<SelectItem> getDistritos() {
        return distritos;
    }

    public void setDistritos(List<SelectItem> distritos) {
        this.distritos = distritos;
    }

    public String getIdDepartamento() {
        return idDepartamento;
    }

    public void setIdDepartamento(String idDepartamento) {
        this.idDepartamento = idDepartamento;
    }

    public String getIdProvincia() {
        return idProvincia;
    }

    public void setIdProvincia(String idProvincia) {
        this.idProvincia = idProvincia;
    }

    public String getIdDistrito() {
        return idDistrito;
    }

    public void setIdDistrito(String idDistrito) {
        this.idDistrito = idDistrito;
    }

    public void setUsuarioSesion(UsuarioControlador usuarioSesion) {
        this.usuarioSesion = usuarioSesion;
    }

    public AmoFiltro getAmoFiltro() {
        return amoFiltro;
    }

    public void setAmoFiltro(AmoFiltro amoFiltro) {
        this.amoFiltro = amoFiltro;
    }
    
    
    
}
